﻿#include "WRWorkTcpCommClientObject.h"
#include "WRWorkTcpCommClientAffair.h"
#include "WRWorkTcpCommClientInterface.h"
#include "WRWorkTcpCommClientInterfaceActivator.h"
#include "../WRWorkTcpComm.h"
#include "../WRWorkTcpCommConsts.h"

//初始化工作对象。
WRWorkTcpCommClientObject::WRWorkTcpCommClientObject(const WRWorkInformation& info, WRType* type, WRWorkTcpCommClientObject* parent, int index, int childCount)
    : WRWorkObject(info, parent), m_type(type), m_index(index), m_affairs(32), m_interfaces(256), m_timeout(WRWorkTcpComm::DefaultTimeount), m_sequence(0), m_procEntry(0)
{
    parent->m_children.append(this);

    m_children.reserve(childCount);
    for(WRu i = 0, l = m_affairs.count(); i < l; ++i)
    {
        m_affairs[i] = 0;
    }
    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        m_interfaces[i] = 0;
    }
}
//初始化工作对象。
WRWorkTcpCommClientObject::WRWorkTcpCommClientObject(const WRWorkInformation& info, WRType* type, WRWorkTcpCommClientSession* session, int index, int childCount)
    : WRWorkObject(info, session), m_type(type), m_index(index), m_affairs(32), m_interfaces(256), m_timeout(WRWorkTcpComm::DefaultTimeount), m_sequence(0), m_procEntry(0)
{
    m_children.reserve(childCount);
    for(WRu i = 0, l = m_affairs.count(); i < l; ++i)
    {
        m_affairs[i] = 0;
    }
    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        m_interfaces[i] = 0;
    }
}
//清理当前对象所占用的相关资源。
WRWorkTcpCommClientObject::~WRWorkTcpCommClientObject(void)
{
    for(WRu i = 0, l = m_affairs.count(); i < l; ++i)
    {
        Affair affair = m_affairs[i];
        if (affair)
        {
            delete affair;
        }
    }
    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        Interface interface = m_interfaces[i];
        if (interface)
        {
            delete interface;
        }
    }
}

//当加载后执行相应的初始工作。
void WRWorkTcpCommClientObject::init(void)
{
    setChildren(m_children);
    WRWorkObject::onInit();
}

//处理数据。
void WRWorkTcpCommClientObject::procData(const unsigned char* buf, int len)
{
    WR16u cmdType = WRBytes::read<WR16u>(buf);
    buf += 2;
    len -= 2;
    switch (cmdType)
    {
    case WRWorkTcpComm::WorkObjectIIQuery://接口查询
    {
        WR32s serial = WRBytes::read<WR32s>(buf);
        buf += 4;
        len -= 4;

        m_procMutex.lock();
        if (m_procEntry && m_procEntry->serial() == serial)
        {
            Interface interface = 0;
            WR32s result = WRBytes::read<WR16s>(buf);
            if (result >= 0)
            {
                WRWorkTcpCommClientInterfaceActivator* activator = WRWorkTcpComm::selectClientInterface(m_procEntry->uuid());
                if (activator)
                {
                    interface = activator->create(result, this);
                    m_interfaces[result] = interface;
                }
            }
            m_procEntry->fulfil(interface);
        }
        m_procMutex.unlock();
    }
        break;
    case WRWorkTcpComm::WorkObjectIITreat://接口处理
    {
        WR16u index = WRBytes::read<WR16u>(buf);
        buf += 2;
        len -= 2;        
        Interface interface = m_interfaces[index];
        if (interface)
        {
            interface->procData(buf, len);
        }
    }
        break;
    case WRWorkTcpComm::WorkObjectAffair://工作事例
    {
        WR32s id = WRBytes::read<WR32s>(buf);
        buf += 4;
        len -= 4;
        WR16u index = WRBytes::read<WR16u>(buf);
        buf += 2;
        len -= 2;
        if (index < m_affairs.count())
        {
            Affair affair = m_affairs[index];
            if (affair && affair->id() == id)
            {
                affair->procData(buf, len);
            }
        }
    }
        break;
    default:
        break;
    }
}

//执行复制操作。
void WRWorkTcpCommClientObject::copyTo(WRWorkTcpCommClientObject* obj)
{
    if (m_children.count()>0)
    {
        for(WRu i = 0, l = m_children.count(); i < l; ++i)
        {
            ((WRWorkTcpCommClientObject*)m_children[(int)i])->clone(obj);
        }
    }

    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        Interface interface = m_interfaces[i];
        if (interface)
        {
            obj->m_interfaces[i] = interface->clone(obj);
        }
    }
}
//根据当前对象创建新对象。
WRWorkTcpCommClientObject* WRWorkTcpCommClientObject::clone(WRWorkTcpCommClientObject* parent)
{
    WRWorkTcpCommClientObject* obj = new WRWorkTcpCommClientObject(info(), m_type, parent, m_index, m_children.count());
    {
        copyTo(obj);
    }
    return obj;
}
//根据当前对象创建新对象。
WRWorkTcpCommClientObject* WRWorkTcpCommClientObject::clone(WRWorkTcpCommClientSession* session)
{
    WRWorkTcpCommClientObject* obj = new WRWorkTcpCommClientObject(info(), m_type, session, m_index, m_children.count());
    {
        copyTo(obj);
    }
    return obj;
}

//获取当前工作对象类型。
WRType* WRWorkTcpCommClientObject::type(void) const
{
    return m_type;
}

//创建工作事务。
WRWorkTcpCommClientAffair* WRWorkTcpCommClientObject::createAffair(int id , int index)
{
    if (index >= (int)m_affairs.count())
    {
        Affars affairs((index + 31) / 32 * 32);
        for(WRu i = 0, l = m_affairs.count(); i < l; ++i)
        {
            affairs[i] = m_affairs[i];
        }
        for(WRu i = m_affairs.count(), l = affairs.count(); i < l; ++i)
        {
            affairs[i] = 0;
        }
        m_affairs = affairs;
    }
    WRWorkTcpCommClientAffair* affair = new WRWorkTcpCommClientAffair(id, index, this);
    m_affairs[index] = affair;
    return affair;
}

//查询指定标识的工作处理者。
WRWorkDealer* WRWorkTcpCommClientObject::queryWorkDealer(const QUuid &uuid)
{
    QMutexLocker lck(&m_mutex);

    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        Interface interface = m_interfaces[i];
        if (interface && interface->uuid() == uuid)
        {
            return interface->workDealer();
        }
    }

    WRWorkTcpCommClientSession* owner = session();
    if (owner->effective())
    {
        ++m_sequence;

        WRDataPacket* packet = WRDataPacket::allocate<48>();
        {
            char* p;
            packet->buffer(&p);

            WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
            WRBytes::write((WR32s)(48), p + 4);//帧长度
            WRBytes::write((WR16u)(m_index), p + 8);//工作对象索引
            WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIIQuery, p + 10);//类型（接口）
            WRBytes::write((WR32s)(m_sequence), p + 12);//指令序号
            WRBytes::write((WR16u)WRWorkTcpComm::WorkDealer, p + 16);//接口标识
            WRBytes::write((QUuid)(uuid), p + 24);//接口标识
            WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 40);//版本
            WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 44);//帧尾
        }

        m_procMutex.lock();
        if (owner->sendData(packet))
        {
            m_procEntry = new ProcEntry(uuid, m_sequence);
        }
        else
        {
            packet->release();
        }
        m_procMutex.unlock();
    }

    if (m_procEntry)
    {
        m_procEntry->wait(m_timeout);

        Interface interface = 0;
        m_procMutex.lock();
        {
            interface = m_procEntry->target();
            delete m_procEntry;
            m_procEntry = 0;
        }
        m_procMutex.unlock();
        if (interface)
        {
            return interface->workDealer();
        }
    }
    return 0;
}
//查询指定标识的任务处理者。
WRTaskDealer* WRWorkTcpCommClientObject::queryTaskDealer(const QUuid& uuid)
{
    QMutexLocker lck(&m_mutex);

    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        Interface interface = m_interfaces[i];
        if (interface && interface->uuid() == uuid)
        {
            return interface->taskDealer();
        }
    }

    WRWorkTcpCommClientSession* owner = session();
    if (owner->effective())
    {
        ++m_sequence;

        WRDataPacket* packet = WRDataPacket::allocate<48>();
        {
            char* p;
            packet->buffer(&p);

            WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
            WRBytes::write((WR32s)(48), p + 4);//帧长度
            WRBytes::write((WR16u)(m_index), p + 8);//工作对象索引
            WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIIQuery, p + 10);//类型（接口）
            WRBytes::write((WR32s)(m_sequence), p + 12);//指令序号
            WRBytes::write((WR16u)WRWorkTcpComm::TaskDealer, p + 16);//接口标识
            WRBytes::write((QUuid)(uuid), p + 24);//接口标识
            WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 40);//版本
            WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 44);//帧尾
        }

        m_procMutex.lock();
        if (owner->sendData(packet))
        {
            m_procEntry = new ProcEntry(uuid, m_sequence);
        }
        else
        {
            packet->release();
        }
        m_procMutex.unlock();
    }

    if (m_procEntry)
    {
        m_procEntry->wait(m_timeout);

        Interface interface = 0;
        m_procMutex.lock();
        {
            interface = m_procEntry->target();
            delete m_procEntry;
            m_procEntry = 0;
        }
        m_procMutex.unlock();
        if (interface)
        {
            return interface->taskDealer();
        }
    }
    return 0;
}
//查询指定标识的数据源接口。
WRDataSource* WRWorkTcpCommClientObject::queryDataSource(const QUuid& uuid)
{
    QMutexLocker lck(&m_mutex);

    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        Interface interface = m_interfaces[i];
        if (interface && interface->uuid() == uuid)
        {
            return interface->dataSource();
        }
    }

    WRWorkTcpCommClientSession* owner = session();
    if (owner->effective())
    {
        ++m_sequence;

        WRDataPacket* packet = WRDataPacket::allocate<48>();
        {
            char* p;
            packet->buffer(&p);

            WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
            WRBytes::write((WR32s)(48), p + 4);//帧长度
            WRBytes::write((WR16u)(m_index), p + 8);//工作对象索引
            WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIIQuery, p + 10);//类型（接口）
            WRBytes::write((WR32s)(m_sequence), p + 12);//指令序号
            WRBytes::write((WR16u)WRWorkTcpComm::DataSource, p + 16);//接口标识
            WRBytes::write((QUuid)(uuid), p + 24);//接口标识
            WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 40);//版本
            WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 44);//帧尾
        }

        m_procMutex.lock();
        if (owner->sendData(packet))
        {
            m_procEntry = new ProcEntry(uuid, m_sequence);
        }
        else
        {
            packet->release();
        }
        m_procMutex.unlock();
    }

    if (m_procEntry)
    {
        m_procEntry->wait(m_timeout);

        Interface interface = 0;
        m_procMutex.lock();
        {
            interface = m_procEntry->target();
            delete m_procEntry;
            m_procEntry = 0;
        }
        m_procMutex.unlock();
        if (interface)
        {
            return interface->dataSource();
        }
    }
    return 0;
}
//查询指定标识的事件源接口。
WREventSource* WRWorkTcpCommClientObject::queryEventSource(const QUuid& uuid)
{
    QMutexLocker lck(&m_mutex);

    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        Interface interface = m_interfaces[i];
        if (interface && interface->uuid() == uuid)
        {
            return interface->eventSource();
        }
    }

    WRWorkTcpCommClientSession* owner = session();
    if (owner->effective())
    {
        ++m_sequence;

        WRDataPacket* packet = WRDataPacket::allocate<48>();
        {
            char* p;
            packet->buffer(&p);

            WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
            WRBytes::write((WR32s)(48), p + 4);//帧长度
            WRBytes::write((WR16u)(m_index), p + 8);//工作对象索引
            WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIIQuery, p + 10);//类型（接口）
            WRBytes::write((WR32s)(m_sequence), p + 12);//指令序号
            WRBytes::write((WR16u)WRWorkTcpComm::EventSource, p + 16);//接口标识
            WRBytes::write((QUuid)(uuid), p + 24);//接口标识
            WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 40);//版本
            WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 44);//帧尾
        }

        m_procMutex.lock();
        if (owner->sendData(packet))
        {
            m_procEntry = new ProcEntry(uuid, m_sequence);
        }
        else
        {
            packet->release();
        }
        m_procMutex.unlock();
    }

    if (m_procEntry)
    {
        m_procEntry->wait(m_timeout);

        Interface interface = 0;
        m_procMutex.lock();
        {
            interface = m_procEntry->target();
            delete m_procEntry;
            m_procEntry = 0;
        }
        m_procMutex.unlock();
        if (interface)
        {
            return interface->eventSource();
        }
    }
    return 0;
}
//查询指示标识的状态源接口。
WRStateSource* WRWorkTcpCommClientObject::queryStateSource(const QUuid& uuid)
{
    QMutexLocker lck(&m_mutex);

    for(WRu i = 0, l = m_interfaces.count(); i < l; ++i)
    {
        Interface interface = m_interfaces[i];
        if (interface && interface->uuid() == uuid)
        {
            return interface->stateSource();
        }
    }

    WRWorkTcpCommClientSession* owner = session();
    if (owner->effective())
    {
        ++m_sequence;

        WRDataPacket* packet = WRDataPacket::allocate<48>();
        {
            char* p;
            packet->buffer(&p);

            WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
            WRBytes::write((WR32s)(48), p + 4);//帧长度
            WRBytes::write((WR16u)(m_index), p + 8);//工作对象索引
            WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIIQuery, p + 10);//类型（接口）
            WRBytes::write((WR32s)(m_sequence), p + 12);//指令序号
            WRBytes::write((WR16u)WRWorkTcpComm::StateSource, p + 16);//接口标识
            WRBytes::write((QUuid)(uuid), p + 24);//接口标识
            WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 40);//版本
            WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 44);//帧尾
        }

        m_procMutex.lock();
        if (owner->sendData(packet))
        {
            m_procEntry = new ProcEntry(uuid, m_sequence);
        }
        else
        {
            packet->release();
        }
        m_procMutex.unlock();
    }

    if (m_procEntry)
    {
        m_procEntry->wait(m_timeout);

        Interface interface = 0;
        m_procMutex.lock();
        {
            interface = m_procEntry->target();
            delete m_procEntry;
            m_procEntry = 0;
        }
        m_procMutex.unlock();
        if (interface)
        {
            return interface->stateSource();
        }
    }
    return 0;
}
